import React, { Component } from 'react';
import { Button, Modal, Form, Input, Checkbox, Card, Row, Col } from 'antd';
import { connect } from 'dva';
import { pageSize, modalWidth } from '../../../config';
import PageHeaderLayout from '@/components/PageHeaderWrapper';
import StandardTable from '../../components/StandardTable';
import tools from '../../utils';

const pageTitle = '系统角色';
const dlgTitle = '角色';
let reqApi = '';
const formItemLayout = {
  labelCol: { md: 3, xs: 7 },
  wrapperCol: { md: 21, xs: 17 },
};
const formItemLayout2 = {
  labelCol: { md: 6, xs: 8 },
  wrapperCol: { md: 18, xs: 16 },
};

const fields = [
  {
    title: dlgTitle + '编号',
    dataIndex: 'id',
    width: 100,
    render: text => <div style={{ color: 'darkgray' }}>{text}</div>,
  },
  {
    title: dlgTitle + '名称',
    dataIndex: 'name',
    type: 'text',
  },
];

// 可见菜单
const opts = {
  ids: [], // 存放复选框id
  checkAll: [], // 是否全选
  checkedList: [], // 已选择的id
  indeterminate: [], // 不完全选择(半选择)
  currCheckId: 0, // 当前鼠标点击的复选框id
};

class page extends Component {
  state = {
    pagination: {
      current: 1,
      pageSize,
      onShowSizeChange: (_, size) => {
        const { pagination } = this.state;
        pagination.pageSize = size;
      },
    },
    dialogAction: 'create',
    dialogTitle: tools.funcDlgTitle(dlgTitle),
  };

  componentWillMount() {
    console.clear();
    reqApi = tools.funcGetApiName();
    const { props } = this;
    props[reqApi].selectOne = false;
    props[reqApi].noSelect = true;
    props[reqApi].dialog_visible = false;
    this.funcReadGrid();
  }

  // 生成复选框组
  funcMakeChecks = () => {
    const { props } = this;
    const { allMenu } = props[reqApi];
    const checks = [];

    for (let i = 0; i < allMenu.length; i += 1) {
      const opt = [];
      const ids = [];

      for (let j = 0; j < allMenu[i].children.length; j += 1) {
        const item = allMenu[i].children[j];
        const { id, name } = item;
        opt.push(
          <Col md={6} xs={12} key={id}>
            <Checkbox
              value={id}
              onClick={e => {
                opts.currCheckId = e.target.value;
              }}
            >
              {name}
            </Checkbox>
          </Col>
        );
        ids.push(id);
      }

      if (opt.length) {
        if (opts.ids.length < allMenu.length) {
          opts.ids.push(ids);
          opts.checkedList.push([]);
          opts.checkAll.push(false);
          opts.indeterminate.push(false);
        }

        const check = (
          <div key={i}>
            <Checkbox
              checked={opts.checkAll[i]}
              indeterminate={opts.indeterminate[i]}
              dataIndex={i} // 自定义一个索引, 方便下面的选择事件调用
              onChange={this.funcOnCheckAllChange}
            >
              {allMenu[i].name}
            </Checkbox>
            <br />
            <Checkbox.Group value={opts.checkedList[i]} onChange={this.funcOnCheckChange}>
              <Row gutter={12} style={{ width: 600 }}>{opt}</Row>
            </Checkbox.Group>
            {i < allMenu.length - 1 ? <div style={{ borderTop: '1px solid lightgray' }} /> : null}
          </div>
        );
        checks.push(check);
      }
    }

    return checks;
  };

  // 复选框组的选择事件
  funcOnCheckChange = checkedList => {
    let index = opts.currCheckId;
    index = index.substr(0, 1);
    index = parseInt(index, 10);
    index -= 1;
    opts.checkedList[index] = checkedList;
    opts.checkAll[index] = opts.ids[index] ? checkedList.length === opts.ids[index].length : false;
    opts.indeterminate[index] = opts.ids[index]
      ? checkedList.length >= 1 && checkedList.length <= opts.ids[index].length - 1
      : false;
    this.setState({});
  };

  funcOnCheckAllChange = e => {
    const index = e.target.dataIndex;
    opts.checkedList[index] = e.target.checked ? opts.ids[index] : [];
    opts.checkAll[index] = e.target.checked;
    opts.indeterminate[index] = false;
    this.setState({});
  };

  // 读取表记录
  funcReadGrid = (params = {}) => {
    const { props, state } = this;
    props[reqApi].loading = true;
    this.setState({});

    const payload = {
      userId: tools.funcGetUserId(),
      token: tools.funcGetToken(),
      currentPage: 1,
      pageSize: state.pagination.pageSize,
      ...params,
    };
    props.dispatch({
      type: reqApi + '/submit',
      payload,
    });
  };

  // 表格翻页
  funcOnChangePage = pagination => {
    const { state } = this;
    state.pagination.current = pagination.current;

    const params = {
      currentPage: pagination.current,
      pageSize: pagination.pageSize,
    };
    this.funcReadGrid(params);
  };

  // 表格行选中事件
  funcSelect = rows => {
    const selectedRowKeys = [];
    for (let i = 0; i < rows.length; i += 1) {
      const { id } = rows[i];
      selectedRowKeys.push(id);
    }

    const { props } = this;
    props[reqApi].noSelect = rows.length === 0;
    props[reqApi].selectOne = rows.length === 1;
    props[reqApi].selectedRowKeys = selectedRowKeys;
    props[reqApi].gridSel_rows = rows;
    this.setState({});
  };

  // 新增
  funcCreate = () => {
    const { props } = this;
    props[reqApi].dialog_visible = true;
    this.setState({
      dialogAction: 'create',
      dialogTitle: tools.funcDlgTitle(dlgTitle),
    }, () => {
      setTimeout(() => {
        this.input.focus();
      }, 100);
    });

    props.form.resetFields();

    // 复选框初始都不选
    for (let i = 0; i < opts.checkAll.length; i += 1) {
      opts.checkedList[i] = [];
      opts.checkAll[i] = false;
      opts.indeterminate[i] = false;
    }

    const payload = {
      userId: tools.funcGetUserId(),
      token: tools.funcGetToken(),
      action: 'create',
    };
    props.dispatch({
      type: reqApi + '/echo',
      payload,
    });
  };

  // 保存
  funcSave = () => {
    const { props, state } = this;
    props.form.validateFields((err, values) => {
      if (err) return err;

      const val = values;
      val.id = props[reqApi].echoId;

      let menus = [];
      for (let i = 0; i < opts.checkAll.length; i += 1) {
        if (opts.checkedList[i].length) {
          let bigId = i + 1;
          bigId = bigId < 10 ? '0' + bigId : '' + bigId;
          menus.push(bigId);
          menus = menus.concat(opts.checkedList[i]);
        }
      }
      val.menus = menus;

      props[reqApi].dialog_loading = true;

      const payload = {
        userId: tools.funcGetUserId(),
        token: tools.funcGetToken(),
        action: state.dialogAction,
        model: val,
      };
      props.dispatch({
        type: reqApi + '/save',
        payload,
      });
      return true;
    });
  };

  // 新增对话框的取消按钮的点击事件
  funcDialogCancel = () => {
    const { props } = this;
    props[reqApi].dialog_visible = false;
    this.setState({});
  };

  // 删除
  funcDelete = () => {
    const { props } = this;
    let names = '';
    for (let i = 0; i < props[reqApi].gridSel_rows.length; i += 1) {
      names += props[reqApi].gridSel_rows[i].name;
      if (i + 1 < props[reqApi].gridSel_rows.length) names += ', ';
    }

    Modal.confirm({
      title: '删除?',
      content: (
        <div>
          你即将删除以下记录:
          <br />
          {names}
          <br />
          请确认是否删除?
        </div>
      ),
      okText: '是',
      okType: 'danger',
      cancelText: '否',
      onOk: () => {
        props[reqApi].loading = true;

        const payload = {
          userId: tools.funcGetUserId(),
          token: tools.funcGetToken(),
          ids: props[reqApi].selectedRowKeys.toString(),
        };
        props.dispatch({
          type: reqApi + '/dele',
          payload,
        });
      },
    });
  };

  // 编辑
  funcEdit = () => {
    const { props } = this;
    props[reqApi].dialog_visible = true;
    this.setState({
      dialogAction: 'edit',
      dialogTitle: tools.funcDlgTitle(dlgTitle, 'edit'),
    }, () => {
      setTimeout(() => {
        this.input.focus();
      });
    });

    const row = { ...props[reqApi].gridSel_rows[0] };
    const { id } = row;
    delete row.id;
    delete row.id_prikey;
    delete row.sequ;

    // 表单输入框赋予初值
    props.form.setFieldsValue(row);

    // 复选框初始都不选
    for (let i = 0; i < opts.checkAll.length; i += 1) {
      opts.checkedList[i] = [];
      opts.checkAll[i] = false;
      opts.indeterminate[i] = false;
    }

    const payload = {
      userId: tools.funcGetUserId(),
      token: tools.funcGetToken(),
      action: 'edit',
      id,
    };
    props.dispatch({
      type: reqApi + '/echo',
      payload,
    }).then(() => {
      const { echoEditArray } = this.props[reqApi];
      for (let i = 0; i < echoEditArray.length; i += 1) {
        const id = echoEditArray[i];
        let index = id.substr(0, 1);
        index = parseInt(index, 10);
        if (index >= 1) {
          index -= 1;
          if (opts.checkedList[index]) opts.checkedList[index].push(id);
        }
      }
      for (let i = 0; i < opts.checkAll.length; i += 1) {
        if (opts.checkedList[i] && opts.ids[i]) {
          if (opts.checkedList[i].length === opts.ids[i].length) {
            opts.checkAll[i] = true;
            opts.indeterminate[i] = false;
          } else if (opts.checkedList[i].length) {
            opts.indeterminate[i] = true;
          }
        }
      }

      this.setState({});
    });
  };

  saveInputRef = input => {
    this.input = input;
  };

  render() {
    const { props, state } = this;
    const { getFieldDecorator } = props.form;

    const data = {
      list: props[reqApi].data,
      pagination: { ...state.pagination, total: props[reqApi].total },
    };

    const btn = props[reqApi].dialog_loading ? '保存' : tools.funcDlgBtnSave();

    return (
      <PageHeaderLayout title={pageTitle}>
        <Card bordered={false}>
          <Button.Group>
            <Button icon="file-add" type="primary" onClick={this.funcCreate}>
              新增
            </Button>
            <Button icon="edit" onClick={this.funcEdit} disabled={!props[reqApi].selectOne}>
              编辑
            </Button>
            <Button
              icon="delete"
              type="danger"
              onClick={this.funcDelete}
              disabled={props[reqApi].noSelect}
            >
              删除
            </Button>
          </Button.Group>
          <br />
          <br />
          <StandardTable
            columns={fields}
            loading={props[reqApi].loading}
            data={data}
            addNum={false}
            onChange={this.funcOnChangePage}
            onSelectRow={this.funcSelect}
            selectedRows={props[reqApi].gridSel_rows}
          />
          <Modal
            width={modalWidth}
            title={state.dialogTitle}
            visible={props[reqApi].dialog_visible}
            onOk={this.funcSave}
            onCancel={this.funcDialogCancel}
            bodyStyle={{
              paddingBottom: 0,
              maxHeight: 'calc(100vh - 265px)',
              overflow: 'auto',
            }}
            footer={[
              <Button key="cancel" onClick={this.funcDialogCancel}>
                {tools.funcDlgBtnCancel()}
              </Button>,
              <Button
                key="ok"
                type="primary"
                onClick={this.funcSave}
                loading={state.dialog_loading}
              >
                {btn}
              </Button>,
            ]}
          >
            <Form>
              <Row gutter={{ md: 24, sm: 8 }}>
                <Col md={12} sm={24}>
                  <Form.Item label="角色名称" {...formItemLayout2}>
                    {getFieldDecorator('name', {
                      rules: [{ required: true, message: '请输入角色名称' }],
                    })(<Input ref={this.saveInputRef} maxLength={20} />)}
                  </Form.Item>
                </Col>
                <Col md={12} sm={24}>
                  <Form.Item label="角色编号" {...formItemLayout2}>
                    <Input disabled value={props[reqApi].echoId} />
                  </Form.Item>
                </Col>
              </Row>
              <Form.Item label="可见菜单" {...formItemLayout} style={{ marginBottom: 0 }}>
                {this.funcMakeChecks()}
              </Form.Item>
            </Form>
          </Modal>
        </Card>
      </PageHeaderLayout>
    );
  }
}

const page2 = Form.create()(page);
export default connect(({ role }) => ({ role }))(page2);
